#! encoding = utf-8

from threading import Thread
import os
import sys
import time
from ArmlogController import ArmLogController
import serial.tools.list_ports as serailListPort
from AutoSanityBsSim.log import AsLogger


class assertLinster(Thread):
    def __init__(self, phObj, port, baudrate, waiteTime):
        super(assertLinster, self).__init__()
        self.PhcObj = phObj
        self.path = os.path.split(os.path.abspath(sys.argv[0]))[0]
        self.assertFlag = False
        self.armLogFlag = False
        self.channelFlag = False

        self.assertApFlag = False
        self.restartFlag = False
        self.online = False

        self.port = port
        self.com = "COM{}".format(port)
        self.baudrate = baudrate

        self.waitTime = waiteTime

    def run(self):
        vid = self.getVidByComName(self.com)
        while True:
            self.checkDiagIsRestart()
            flag, u2sDiag = self.getU2SDiagFlag(vid)
            if flag and str(u2sDiag).upper().__contains__('COM'):
                AsLogger().info('find u2s diag port for first time')
                time.sleep(self.waiteTime)
                flag, u2sDiag = self.getU2SDiagFlag(vid)
                if flag and str(u2sDiag).upper().__contains__('COM'):
                    AsLogger().info('find u2s diag port for second time')
                    self.assertApCatch(u2sDiag)

            self.assertMsCatch()
            time.sleep(10)

    def assertMsCatch(self):
        file_list = os.listdir(self.path)
        for name in file_list:
            if name == "Assert.ass":
                if self.armLogFlag:
                    self.assertFlag = True
                    time.sleep(10)
                    self.freeDiag()
                    time.sleep(3)

                    self.catcherLogelWhenAssertMs()

                    self.initDiag()

                    self.assertFlag = False
                elif self.channelFlag:
                    AsLogger().info('channelFlag is True')
                    self.assertFlag = True
                    self.PhcObj.sendAssertPrintCommand("t")
                    time.sleep(600)
                    self.assertFlag = False
                os.remove(os.path.join(self.path, name))
            time.sleep(1)

    def assertApCatch(self, u2sDiag):
        self.assertFlag = True
        self.catcherLogelWhenAssertAP(u2sDiag)
        self.assertFlag = False

        if self.restartFlag:
            self.restartOnline()
        time.sleep(3)

    def getVidByComName(self, com_port="COM1"):
        for portInfo in self.getAllComInfo():
            if portInfo.device.lower() == com_port.lower():
                return portInfo.vid

    def getAllComInfo(self):
        return serailListPort.comports()

    def getAssertFlag(self):
        return self.assertFlag

    def openArmLogCatcherLog(self, armLogPath, diagPort):
        self.armLogPath = armLogPath
        self.diagPort = diagPort
        self.logDir = os.path.join(self.path, 'assertMsLog')
        if not os.path.exists(self.logDir):
            os.mkdir(self.logDir)
        self.armLogFlag = True

        self.apLogDir = os.path.join(self.path, 'assertApLog')
        if not os.path.exists(self.apLogDir):
            os.mkdir(self.apLogDir)

    def openChannel(self):
        self.channelFlag = True

    def catcherLogelWhenAssertMs(self):
        armLogControllerObj = ArmLogController(self.diagPort, self.armLogPath, self.logDir)
        armLogControllerObj.startArmlog()
        time.sleep(5*60)
        bt = time.time()

        while True:
            et = time.time()
            ht = (et - bt) / 60
            if armLogControllerObj.checkAssertIsEnd() or ht > 20:
                armLogControllerObj.closedArmLog()
                time.sleep(3)
                armLogControllerObj.moveLog()
                break
            time.sleep(5 * 60)


    def catcherLogelWhenAssertAP(self, u2sDiagPort):

        armLogControllerObj = ArmLogController(u2sDiagPort, self.armLogPath, self.apLogDir )
        armLogControllerObj.startArmlog()
        time.sleep(5 * 60)
        bt = time.time()
        while True:
            et = time.time()
            ht = (et - bt) / 60
            if armLogControllerObj.checkAssertIsEnd() or ht > 20:
                armLogControllerObj.closedArmLog()
                time.sleep(3)
                armLogControllerObj.moveLog()
                break

            time.sleep(5*60)

    def freeDiag(self):

        self.PhcObj.SP_EndPhoneTest()
        self.PhcObj.SP_ReleasePhone()


    def initDiag(self):

        self.PhcObj.loaddll()
        self.PhcObj.createISplog()
        self.PhcObj.SP_CreatePhone()
        self.PhcObj.SP_BeginPhoneTest(self.port, self.baudrate)



    def checkDiagIsRestart(self):
        com_list = []
        for portInfo in self.getAllComInfo():
            com_list.append(portInfo.device.lower())

        if self.com.lower() not in com_list:
            self.restartFlag = True

    def checkDiagIsOnline(self):
        for portInfo in self.getAllComInfo():
            if portInfo.device.lower() == self.com.lower():
                self.online = True
                return
        self.online = False

    def restartOnline(self):
        self.checkDiagIsOnline()
        if self.online == True:
            # self.Obj.SP_BeginPhoneTest(int(str(port)[3:]) if "com" in str(port).lower() else int(port), self.baudrate)
            self.initDiag()
            self.restartFlag = False

    def getAssertApFlag(self):
        return self.assertFlag

    def getU2SDiagFlag(self, vid):
        for portInfo in self.getAllComInfo():
            if portInfo.description.lower().find(u"sprd u2s diag") != -1 and vid == portInfo.vid:
                AsLogger().info("find u2s port, com is {}".format(portInfo.device))
                return True, portInfo.device
        return False, None

    def getDiagPort(self,com):
        vid = self.getVidByComName(com)
        for portInfo in self.getAllComInfo():
            if portInfo.description.lower().find(u"sprd diag") != -1 and vid == portInfo.vid:
                return int(str(portInfo.device)[3:]) if "com" in str(portInfo.device).lower() else int(portInfo.device)